<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:db="http://docbook.org/ns/docbook"
    xmlns:pbs="http://schema.pbs.gov.au" xmlns:g2g="http://schema.pbs.gov.au/Agency"
    xmlns:rwt="http://schema.pbs.gov.au/RWT/" xmlns:dct="http://purl.org/dc/terms/" version="1.0">

    <xsl:import href="common.xsl"/>

    <db:article>
        <db:info>
            <db:title>PBS Item Table Extract File</db:title>

            <db:copyright>
                <db:year>2013</db:year>
                <db:year>2012</db:year>
                <db:year>2011</db:year>
                <db:year>2009</db:year>
                <db:holder>Commonwealth of Australia</db:holder>
            </db:copyright>

            <db:legalnotice>
                <db:para>This software is copyrighted by the Commonwealth of Australia ("The
                    Commonwealth"). The following terms apply to all files associated with the
                    software unless explicitly disclaimed in individual files.</db:para>
                <db:para>Permission is hereby granted to use, copy, modify, distribute, and license
                    this software and its documentation for any purpose, provided that existing
                    copyright notices are retained in all copies and that this notice is included
                    verbatim in any distributions. No written agreement, license, or royalty fee is
                    required for any of the authorized uses. Modifications to this software may be
                    copyrighted by their authors and need not follow the licensing terms described
                    here, provided that the new terms are clearly indicated on the first page of
                    each file where they apply.</db:para>
                <db:para>IN NO EVENT SHALL THE COMMONWEALTH OR DISTRIBUTORS BE LIABLE TO ANY PARTY
                    FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
                    OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN
                    IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</db:para>
                <db:para>THE COMMONWEALTH SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT
                    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
                    PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
                    AND THE COMMONWEALTH HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
                    ENHANCEMENTS, OR MODIFICATIONS.</db:para>
            </db:legalnotice>

            <db:author>
                <db:personname>Steve Ball</db:personname>
                <db:email>Steve.Ball@health.gov.au</db:email>
                <db:affiliation>
                    <db:orgname>Department of Health and Ageing</db:orgname>
                    <db:orgdiv>PharmBiz</db:orgdiv>
                </db:affiliation>
            </db:author>
            <db:author>
                <db:personname>Daryl Maclean</db:personname>
                <db:email>Daryl.Maclean@health.gov.au</db:email>
                <db:affiliation>
                    <db:orgname>Department of Health and Ageing</db:orgname>
                    <db:orgdiv>PharmBiz</db:orgdiv>
                </db:affiliation>
            </db:author>

            <db:revhistory>
                <db:revision>
                    <db:revnumber>3.7</db:revnumber>
                    <db:date>2013-11-06</db:date>
                    <db:authorinitials>SRB</db:authorinitials>
                    <db:revremark>Use before and after restriction level to find all changed prescribing rules</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>3.6</db:revnumber>
                    <db:date>2013-08-08</db:date>
                    <db:authorinitials>SRB</db:authorinitials>
                    <db:revremark>Check source document is appropriate.</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>3.5.1</db:revnumber>
                    <db:date>2013-07-22</db:date>
                    <db:authorinitials>SRB</db:authorinitials>
                    <db:revremark>Fixed note processing.</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>3.5</db:revnumber>
                    <db:date>2013-07-05</db:date>
                    <db:authorinitials>JPK</db:authorinitials>
                    <db:revremark>Remove rwt:prescriber-instruction content from
                        notes.</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>3.4.1</db:revnumber>
                    <db:date>2012-11-27</db:date>
                    <db:authorinitials>SRB</db:authorinitials>
                    <db:revremark>Fixed setting of schedule indicator flag.</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>3.4</db:revnumber>
                    <db:date>2012-11-09</db:date>
                    <db:authorinitials>SRB</db:authorinitials>
                    <db:revremark>Change priority of start date - restriction-reference is used
                        first.</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>3.3.2</db:revnumber>
                    <db:date>2012-11-07</db:date>
                    <db:authorinitials>DMM</db:authorinitials>
                    <db:revremark>Added documentation on the output format.</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>3.3.1</db:revnumber>
                    <db:date>2012-11-05</db:date>
                    <db:authorinitials>SRB</db:authorinitials>
                    <db:revremark>Empty end date is represented as eight spaces.</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>3.3</db:revnumber>
                    <db:date>2012-11-01</db:date>
                    <db:authorinitials>SRB</db:authorinitials>
                    <db:revremark>Supply default non-effective date.</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>3.2</db:revnumber>
                    <db:date>2012-10-22</db:date>
                    <db:authorinitials>SRB</db:authorinitials>
                    <db:revremark>Ignore constraints notes.</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>3.1</db:revnumber>
                    <db:date>2012-09-18</db:date>
                    <db:authorinitials>DMM</db:authorinitials>
                    <db:revremark>Bug fixes: 1) No longer pad caution and note ids with 0s in
                        pharmacy mode. 2) Remove extra delimeter output before the first note and
                        first caution. 3) Correct the number of cautions to 5 (from
                        4).</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>3.0</db:revnumber>
                    <db:date>2012-08-29</db:date>
                    <db:authorinitials>SRB</db:authorinitials>
                    <db:revremark>Improve inclusion of start and end dates.</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>2.16</db:revnumber>
                    <db:date>2012-08-15</db:date>
                    <db:authorinitials>DMM</db:authorinitials>
                    <db:revremark>Added processing of rwt:administrative-advice and
                        rwt:administrative-advice-reference children of rwt:restriction when
                        extracting notes.</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>2.15</db:revnumber>
                    <db:date>2012-04-23</db:date>
                    <db:authorinitials>DMM</db:authorinitials>
                    <db:revremark>Remove trailing tab character at end of each line. Remove empty
                        '0000' values for notes and cautions between valid values.</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>2.14</db:revnumber>
                    <db:date>2012-04-03</db:date>
                    <db:authorinitials>DMM</db:authorinitials>
                    <db:revremark>Fix bugs relating to duplicate notes / cautions code output; and
                        extra trailing space on start and end dates</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>2.13</db:revnumber>
                    <db:date>2012-02-21</db:date>
                    <db:authorinitials>SRB</db:authorinitials>
                    <db:revremark>Upgrade to v2.7 PBS XML Schema</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>2.12</db:revnumber>
                    <db:date>2012-02-10</db:date>
                    <db:authorinitials>SRB</db:authorinitials>
                    <db:revremark>IP program is not considered to be in CPAP</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>2.11</db:revnumber>
                    <db:date>2011-11-29</db:date>
                    <db:authorinitials>BD</db:authorinitials>
                    <db:revremark>Fix identification of cautions inside restrictions</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>2.10</db:revnumber>
                    <db:date>2011-11-24</db:date>
                    <db:authorinitials>BD</db:authorinitials>
                    <db:revremark>Only one row per item code</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>2.9</db:revnumber>
                    <db:date>2011-11-21</db:date>
                    <db:authorinitials>BD</db:authorinitials>
                    <db:revremark>Pad note and catuion numbers. Exclude non-numeric note and caution
                        numbers</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>2.8</db:revnumber>
                    <db:date>2011-11-14</db:date>
                    <db:authorinitials>DMM</db:authorinitials>
                    <db:revremark>Modified keys to address performance issues</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>2.7</db:revnumber>
                    <db:date>2011-11-04</db:date>
                    <db:authorinitials>SRB</db:authorinitials>
                    <db:revremark>Reverse meaning of type parameter.</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>2.6</db:revnumber>
                    <db:date>2011-11-03</db:date>
                    <db:authorinitials>SRB</db:authorinitials>
                    <db:revremark>Changed is-cpap to not consider "IP" as in CPAP.</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>2.5</db:revnumber>
                    <db:date>2011-10-26</db:date>
                    <db:authorinitials>SRB</db:authorinitials>
                    <db:revremark>Added bug compatibility.</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>2.4</db:revnumber>
                    <db:date>2011-10-25</db:date>
                    <db:authorinitials>SRB</db:authorinitials>
                    <db:revremark>Fixed MQ and rpt values. Added pharmacy parameter.</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>2.3</db:revnumber>
                    <db:date>2011-10-12</db:date>
                    <db:authorinitials>SRB</db:authorinitials>
                    <db:revremark>Fixed notes and cautions to prevent blank lines. Note and caution
                        IDs are no longer zero-padded.</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>2.2</db:revnumber>
                    <db:date>2011-08-01</db:date>
                    <db:authorinitials>DMM</db:authorinitials>
                    <db:revremark>Fixed 'translate' statements with incorrect number of
                        parameters.</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>2.1</db:revnumber>
                    <db:date>2011-06-16</db:date>
                    <db:authorinitials>SRB</db:authorinitials>
                    <db:revremark>Fixed format issues.</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>2.0</db:revnumber>
                    <db:date>2011-02-19</db:date>
                    <db:authorinitials>SRB</db:authorinitials>
                    <db:revremark>Updated for PBS XML Schema v2.4.</db:revremark>
                </db:revision>
                <db:revision>
                    <db:revnumber>1.0</db:revnumber>
                    <db:date>2009-10-02</db:date>
                    <db:authorinitials>SRB</db:authorinitials>
                    <db:revremark>Initial version.</db:revremark>
                </db:revision>
            </db:revhistory>
        </db:info>

        <db:para>This XSL stylesheet produces the PBS Item Table ANS extract file (<db:filename>PBS
                Item Table yyyymmdd.txt</db:filename>) from a PBS XML document.</db:para>
        <db:para>The Item extract file provides information on the availability of items through the
            eAuthorities system, and also links Notes and Cautions to the PBS item codes.</db:para>
        <db:para>The source document must be the result of the <db:filename>delta.xsl</db:filename>
            XSL stylesheet.</db:para>
        <db:para>The result document is a text file.</db:para>
        <db:para>The default field delimeter in this file is the tab character.</db:para>
        <db:table>
            <db:tgroup cols="5" align="left" colsep="1" rowsep="1">
                <db:colspec colnum="3" align="right"/>
                <db:colspec colnum="4" align="right"/>
                <db:thead>
                    <db:row>
                        <db:entry>Field Name</db:entry>
                        <db:entry>Format</db:entry>
                        <db:entry>Maximum Length</db:entry>
                        <db:entry>Start Position</db:entry>
                        <db:entry>Description</db:entry>
                    </db:row>
                </db:thead>
                <db:tbody>
                    <db:row>
                        <db:entry>PBS Item Code</db:entry>
                        <db:entry>Character</db:entry>
                        <db:entry>6</db:entry>
                        <db:entry>1</db:entry>
                        <db:entry>five or six characters in format (n)nnnna</db:entry>
                    </db:row>
                    <db:row>
                        <db:entry>Restriction Flag</db:entry>
                        <db:entry>Character</db:entry>
                        <db:entry>1</db:entry>
                        <db:entry>7</db:entry>
                        <db:entry>
                            <db:para>Indicates the restriction level for this PBS item, for
                                quantity/repeats within the schedule limit.</db:para>
                            <db:simplelist>
                                <db:member>A=Authority required</db:member>
                                <db:member>R=Restricted Benefit</db:member>
                                <db:member>U=Unrestricted</db:member>
                            </db:simplelist>
                        </db:entry>
                    </db:row>
                    <db:row>
                        <db:entry>eAuthorities quantity</db:entry>
                        <db:entry>Character</db:entry>
                        <db:entry>2</db:entry>
                        <db:entry>9</db:entry>
                        <db:entry>For use by Medicare Australia only. </db:entry>
                    </db:row>
                    <db:row>
                        <db:entry>eAuthorities Repeats</db:entry>
                        <db:entry>Character</db:entry>
                        <db:entry>2</db:entry>
                        <db:entry>12</db:entry>
                        <db:entry>For use by Medicare Australia only. </db:entry>
                    </db:row>
                    <db:row>
                        <db:entry>eAuthorities Flag</db:entry>
                        <db:entry>Character</db:entry>
                        <db:entry>1</db:entry>
                        <db:entry>15</db:entry>
                        <db:entry>For use by Medicare Australia only. </db:entry>
                    </db:row>
                    <db:row>
                        <db:entry>Schedule Indicator</db:entry>
                        <db:entry>Character</db:entry>
                        <db:entry>1</db:entry>
                        <db:entry>17</db:entry>
                        <db:entry>For use by Medicare Australia only. </db:entry>
                    </db:row>
                    <db:row>
                        <db:entry>Start Date</db:entry>
                        <db:entry>Character</db:entry>
                        <db:entry>8</db:entry>
                        <db:entry>19</db:entry>
                        <db:entry>format ddmmyyyy</db:entry>
                    </db:row>
                    <db:row>
                        <db:entry>End Date</db:entry>
                        <db:entry>Character</db:entry>
                        <db:entry>8</db:entry>
                        <db:entry>28</db:entry>
                        <db:entry>format ddmmyyyy. May be blank if the item is current (no end date
                            has been set).</db:entry>
                    </db:row>
                    <db:row>
                        <db:entry>Note Ids</db:entry>
                        <db:entry>Character</db:entry>
                        <db:entry>60</db:entry>
                        <db:entry>37</db:entry>
                        <db:entry>Array of 15 x 4 character numerics. The Note Id of any Note(s)
                            attached to the drug name, the item or the restriction. There is
                            provision for up to fifteen Notes</db:entry>
                    </db:row>
                    <db:row>
                        <db:entry>Caution Ids</db:entry>
                        <db:entry>Character</db:entry>
                        <db:entry>60</db:entry>
                        <db:entry>98</db:entry>
                        <db:entry>Array of 5 x 4 character numerics. The Caution Id of any
                            Caution(s) attached to the drug name, the item or the restriction. There
                            is provision for up to five Cautions</db:entry>
                    </db:row>
                </db:tbody>
            </db:tgroup>
        </db:table>
    </db:article>

    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>

    <db:param name="type">
        <db:refpurpose>Output Type</db:refpurpose>
        <db:para>Specifies whether to generate the text output with or without eAuthority values.
            Default "normal" (ie. with eAuthority values). Valid values: "normal", "pharmacy". NB.
            This is also driven by the data (ie. if "normal" is selected but the data does not
            contain eAuthority values then the result will be the same as if "pharmacy" were
            selected).</db:para>
    </db:param>
    <xsl:param name="type" select="'normal'"/>

    <db:param name="bug-compatible">
        <db:refpurpose>Bug Compatibility</db:refpurpose>
        <db:para>Specifies whether to generate date values properly, ie "DDMMYYY", or to be
            bug-compatible with PBDS, ie. "DMMYYYY". Default "no" (ie. not bug compatible). Valid
            values: "no", "yes".</db:para>
    </db:param>
    <xsl:param name="bug-compatible" select="'no'"/>

    <db:param name="delimiter">
        <db:refpurpose>Field Delimiter</db:refpurpose>
        <db:para>Delimiter to use between fields. Default is tab character.</db:para>
    </db:param>
    <xsl:param name="delimiter" select="'&#x9;'"/>

    <db:param name="eol">
        <db:refpurpose>Record Delimiter</db:refpurpose>
        <db:para>Delimiter to use between records. Default is newline character.</db:para>
    </db:param>
    <xsl:param name="eol" select="'&#xa;'"/>

    <xsl:key name="ident" match="*" use="@xml:id"/>

    <db:template name="root">
        <db:refpurpose>Check Document Version</db:refpurpose>
        <db:para>Make sure that the source document uses the correct version of the PBS XML
            Schema.</db:para>
    </db:template>
    <xsl:template match="/">
        <xsl:variable name="major" select="substring-before(/*/@version, '.')"/>

        <xsl:choose>
            <xsl:when test="$major >= 2 and
                /pbs:root/pbs:schedule/pbs:listings-list/pbs:prescribing-rule/before">
                <xsl:apply-templates
                    select="/pbs:root/pbs:schedule/pbs:listings-list/pbs:prescribing-rule"/>
            </xsl:when>
            <xsl:when test="$major >= 2">
                <xsl:message terminate="yes">The source document must be processed using the delta.xsl stylesheet before using this stylesheet.</xsl:message>
            </xsl:when>
            <xsl:otherwise>
                <xsl:message terminate="yes">This stylesheet is designed to operate upon a Schedule
                    XML document that conforms to version 2.8 (or later) of the PBS XML Schema. See
                    http://dev.pbs.gov.au/ for more information on the PBS XML Schema, and for a
                    version of this XSL stylesheet that operates on documents that conform to an
                    earlier version of the schema.</xsl:message>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template match="pbs:prescribing-rule">
        <xsl:variable name="before">
            <xsl:call-template name="make-row">
                <xsl:with-param name="item" select="."/>
                <xsl:with-param name="item-code" select="*[node()][1]/pbs:code"/>
                <xsl:with-param name="level" select="before/@type"/>
                <xsl:with-param name="nodes" select="before/node()"/>
                <xsl:with-param name="compare" select="true()"/>
            </xsl:call-template>
        </xsl:variable>
        <xsl:variable name="after">
            <xsl:call-template name="make-row">
                <xsl:with-param name="item" select="."/>
                <xsl:with-param name="item-code" select="*[node()][1]/pbs:code"/>
                <xsl:with-param name="level" select="after/@type"/>
                <xsl:with-param name="nodes" select="after/node()"/>
                <xsl:with-param name="compare" select="true()"/>
            </xsl:call-template>
        </xsl:variable>

        <xsl:choose>
            <xsl:when test="before/node() and after/node() and
        $before = $after">
                <xsl:call-template name="make-row">
                    <xsl:with-param name="item" select="."/>
                    <xsl:with-param name="item-code" select="*[node()][1]/pbs:code"/>
                    <xsl:with-param name="level" select="after/@type"/>
                    <xsl:with-param name="nodes" select="after/node()"/>
                    <xsl:with-param name="compare" select="false()"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:when test="before/node() and after/node()">
                <xsl:call-template name="make-row">
                    <xsl:with-param name="item" select="."/>
                    <xsl:with-param name="item-code" select="*[node()][1]/pbs:code"/>
                    <xsl:with-param name="level" select="after/@type"/>
                    <xsl:with-param name="nodes" select="after/node()"/>
                    <xsl:with-param name="compare" select="false()"/>
                </xsl:call-template>
                <xsl:call-template name="make-row">
                    <xsl:with-param name="item" select="."/>
                    <xsl:with-param name="item-code" select="*[node()][1]/pbs:code"/>
                    <xsl:with-param name="level" select="before/@type"/>
                    <xsl:with-param name="nodes" select="before/node()"/>
                    <xsl:with-param name="compare" select="false()"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:when test="before/node()">
                <xsl:call-template name="make-row">
                    <xsl:with-param name="item" select="."/>
                    <xsl:with-param name="item-code" select="*[node()][1]/pbs:code"/>
                    <xsl:with-param name="level" select="before/@type"/>
                    <xsl:with-param name="nodes" select="before/node()"/>
                    <xsl:with-param name="compare" select="false()"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <!-- only after -->
                <xsl:call-template name="make-row">
                    <xsl:with-param name="item" select="."/>
                    <xsl:with-param name="item-code" select="*[node()][1]/pbs:code"/>
                    <xsl:with-param name="level" select="after/@type"/>
                    <xsl:with-param name="nodes" select="after/node()"/>
                    <xsl:with-param name="compare" select="false()"/>
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template name="make-row">
        <xsl:param name="item" select="/.."/>
        <xsl:param name="item-code"/>
        <xsl:param name="level"/>
        <xsl:param name="nodes" select="/.."/>
        <xsl:param name="compare" select="false()"/>

        <xsl:variable name="eauth.mq.raw">
            <xsl:apply-templates
                select="$nodes/rwt:restriction-references-list/rwt:restriction-reference"
                mode="eauth.mq"/>
        </xsl:variable>
        <xsl:variable name="eauth.mq">
            <xsl:choose>
                <xsl:when test="contains($eauth.mq.raw, ' ')">
                    <xsl:value-of select="substring-before($eauth.mq.raw, ' ')"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$eauth.mq.raw"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>

        <xsl:variable name="cpap.mq.raw">
            <xsl:apply-templates
                select="$nodes/rwt:restriction-references-list/rwt:restriction-reference"
                mode="cpap.mq"/>
        </xsl:variable>
        <xsl:variable name="cpap.mq">
            <xsl:choose>
                <xsl:when test="contains($cpap.mq.raw, ' ')">
                    <xsl:value-of select="substring-before($cpap.mq.raw, ' ')"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$cpap.mq.raw"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>

        <xsl:variable name="eauth.rpts.raw">
            <xsl:apply-templates
                select="$nodes/rwt:restriction-references-list/rwt:restriction-reference"
                mode="eauth.rpts"/>
        </xsl:variable>
        <xsl:variable name="eauth.rpts">
            <xsl:choose>
                <xsl:when test="contains($eauth.rpts.raw, ' ')">
                    <xsl:value-of select="substring-before($eauth.rpts.raw, ' ')"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$eauth.rpts.raw"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <xsl:variable name="eauth.rpts.num" select="translate($eauth.rpts, '0123456789', '') = ''"/>

        <xsl:variable name="cpap.rpts.raw">
            <xsl:apply-templates
                select="$nodes/rwt:restriction-references-list/rwt:restriction-reference"
                mode="cpap.rpts"/>
        </xsl:variable>
        <xsl:variable name="cpap.rpts">
            <xsl:choose>
                <xsl:when test="contains($cpap.rpts.raw, ' ')">
                    <xsl:value-of select="substring-before($cpap.rpts.raw, ' ')"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$cpap.rpts.raw"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <xsl:variable name="cpap.rpts.num" select="translate($cpap.rpts, '0123456789', '') = ''"/>

        <xsl:variable name="is-cpap"
            select="ancestor::pbs:listings-list/pbs:info/pbs:code = 'CT' or
            ancestor::pbs:listings-list/pbs:info/pbs:code = 'CS'"/>

        <xsl:variable name="is-infusible"
            select="ancestor::pbs:listings-list/pbs:info/pbs:pricing-model = 'http://schema.pbs.gov.au/Pricing/infusible'"/>

        <xsl:variable name="eauth-flag"
            select="number($cpap.mq) > 0 or 
            (number($eauth.mq) > 0 and not($is-cpap))"/>

        <xsl:variable name="total.mq.raw">
            <xsl:apply-templates
                select="$nodes/rwt:restriction-references-list/rwt:restriction-reference"
                mode="total.mq"/>
        </xsl:variable>
        <xsl:variable name="total.mq.norm" select="normalize-space($total.mq.raw)"/>
        <xsl:variable name="total.mq">
            <xsl:choose>
                <xsl:when test="$total.mq.norm = ''">0</xsl:when>
                <xsl:when test="contains($total.mq.norm, ' ')">
                    <xsl:value-of select="substring-before($total.mq.norm, ' ')"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$total.mq.norm"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <xsl:variable name="total.rpts.raw">
            <xsl:apply-templates
                select="$nodes/rwt:restriction-references-list/rwt:restriction-reference"
                mode="total.rpts"/>
        </xsl:variable>
        <xsl:variable name="total.rpts.norm" select="normalize-space($total.rpts.raw)"/>
        <xsl:variable name="total.rpts">
            <xsl:choose>
                <xsl:when test="$total.rpts.norm = ''">0</xsl:when>
                <xsl:when test="contains($total.rpts.norm, ' ')">
                    <xsl:value-of select="substring-before($total.rpts.norm, ' ')"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$total.rpts.norm"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>

        <!-- Start Date -->
        <!-- Need to find the most recent change to PR or notes or cautions -->
        <xsl:variable name="latest">
            <xsl:choose>
                <xsl:when test="$nodes/self::pbs:effectivity/start">
                    <xsl:value-of select="$nodes/self::pbs:effectivity/start"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:call-template name="find-latest">
                        <xsl:with-param name="dates">
                            <xsl:value-of select="$nodes[self::pbs:effectivity]/pbs:start"/>
                            <xsl:for-each
                                select="$nodes/rwt:restriction-references-list/rwt:restriction-reference/pbs:effectivity/pbs:start">
                                <xsl:text> </xsl:text>
                                <xsl:value-of select="."/>
                            </xsl:for-each>
                            <!-- start dates of restriction-(note|caution) relationships -->
                            <xsl:apply-templates select="$nodes/rwt:restriction-references-list/*"
                                mode="note-start"/>
                        </xsl:with-param>
                    </xsl:call-template>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>

        <xsl:variable name="notes">
            <xsl:apply-templates
                select="$nodes/rwt:restriction-references-list/rwt:restriction-reference"
                mode="note"/>
        </xsl:variable>

        <xsl:variable name="cautions">
            <xsl:apply-templates
                select="$nodes/rwt:restriction-references-list/rwt:restriction-reference"
                mode="caution"/>
        </xsl:variable>

        <xsl:call-template name="create-row">
            <xsl:with-param name="item" select="$item"/>
            <xsl:with-param name="item-code" select="$item-code"/>
            <xsl:with-param name="level" select="$level"/>
            <xsl:with-param name="eauth.mq">
                <xsl:choose>
                    <xsl:when test="not($eauth-flag) and
                        not($is-cpap)"
                        >0</xsl:when>
                    <xsl:when test="$is-cpap">
                        <xsl:call-template name="pad-number">
                            <xsl:with-param name="number" select="$cpap.mq"/>
                            <xsl:with-param name="length" select="2"/>
                            <xsl:with-param name="pad" select="'0'"/>
                        </xsl:call-template>
                    </xsl:when>
                    <xsl:when test="not($is-cpap)">
                        <xsl:call-template name="pad-number">
                            <xsl:with-param name="number" select="$eauth.mq"/>
                            <xsl:with-param name="length" select="2"/>
                            <xsl:with-param name="pad" select="'0'"/>
                        </xsl:call-template>
                    </xsl:when>
                    <xsl:otherwise>0</xsl:otherwise>
                </xsl:choose>
            </xsl:with-param>
            <xsl:with-param name="eauth.rpts">
                <xsl:choose>
                    <xsl:when test="not($eauth-flag) and
                        not($is-cpap)"
                        >0</xsl:when>
                    <xsl:when test="$is-cpap">0</xsl:when>
                    <xsl:when test="$nodes/pbs:number-repeats">
                        <xsl:call-template name="pad-number">
                            <xsl:with-param name="number"
                                select="$nodes/pbs:number-repeats + $eauth.rpts"/>
                            <xsl:with-param name="length" select="2"/>
                            <xsl:with-param name="pad" select="'0'"/>
                        </xsl:call-template>
                    </xsl:when>
                    <xsl:otherwise>0</xsl:otherwise>
                </xsl:choose>
            </xsl:with-param>
            <xsl:with-param name="eauth.flag">
                <xsl:choose>
                    <xsl:when test="$is-cpap">N</xsl:when>
                    <xsl:when test="$eauth-flag">Y</xsl:when>
                    <xsl:otherwise>N</xsl:otherwise>
                </xsl:choose>
            </xsl:with-param>
            <xsl:with-param name="sch.ind">
                <xsl:choose>
                    <xsl:when
                        test="(number($total.mq) > 1 or $total.mq = 'unspecified') and
                        (number($total.rpts) > 0 or $total.rpts = 'unspecified')"
                        >1</xsl:when>
                    <xsl:when
                        test="number($total.mq) = 1 and
                        number($total.rpts) = 0"
                        >2</xsl:when>
                    <xsl:when
                        test="(number($total.mq) > 1 or $total.mq = 'unspecified') and
                        number($total.rpts) = 0"
                        >3</xsl:when>
                    <xsl:when
                        test="number($total.mq) = 1 and
                        (number($total.rpts) > 0 or $total.rpts = 'unspecified')"
                        >4</xsl:when>
                    <xsl:otherwise>2</xsl:otherwise>
                </xsl:choose>
            </xsl:with-param>
            <xsl:with-param name="start">
                <xsl:if test="not($compare)">
                    <xsl:value-of select="$latest"/>
                </xsl:if>
            </xsl:with-param>
            <xsl:with-param name="end">
                <xsl:if test="not($compare) and $nodes/ancestor::before">
                    <xsl:call-template name="find-latest">
                        <xsl:with-param name="dates">
                            <xsl:value-of select="$nodes[self::pbs:effectivity]/pbs:non-effective"/>
                            <xsl:for-each
                                select="$nodes/rwt:restriction-references-list/rwt:restriction-reference/pbs:effectivity/pbs:non-effective">
                                <xsl:text> </xsl:text>
                                <xsl:value-of select="."/>
                            </xsl:for-each>
                            <!-- end dates of restriction-(note|caution) relationships -->
                            <xsl:apply-templates select="$nodes/rwt:restriction-references-list/*"
                                mode="note-end"/>
                        </xsl:with-param>
                        <xsl:with-param name="default" select="/pbs:root/pbs:info/dct:valid"/>
                    </xsl:call-template>
                </xsl:if>
            </xsl:with-param>
            <xsl:with-param name="note.ids" select="$notes"/>
            <xsl:with-param name="caution.ids" select="$cautions"/>
        </xsl:call-template>
    </xsl:template>

    <xsl:template
        match="rwt:restriction-reference |
        rwt:circumstance-reference |
        rwt:administrative-advice-reference |
        rwt:definition-reference"
        mode="note">

        <xsl:apply-templates
            select="key('ident', substring(@xlink:href, 2))[
            self::rwt:restriction |
            self::rwt:circumstance |
            self::rwt:caution |
            self::rwt:administrative-advice |
            self::rwt:definition]"
            mode="note"/>
    </xsl:template>
    <xsl:template match="rwt:restriction" mode="note">
        <xsl:apply-templates
            select="rwt:circumstance |
                    rwt:circumstance-reference |
                    rwt:administrative-advice |
                    rwt:administrative-advice-reference |
                    rwt:definition |
                    rwt:definition-reference"
            mode="note"/>
    </xsl:template>
    <xsl:template match="rwt:circumstance" mode="note">
        <xsl:apply-templates
            select="rwt:administrative-advice |
                    rwt:administrative-advice-reference"
            mode="note"/>
    </xsl:template>
    <xsl:template match="rwt:administrative-advice |
        rwt:definition" mode="note">

        <xsl:if
            test="pbs:code and
            not(rwt:constraints/* and contains(db:note, 'Flag Set'))">
            <xsl:value-of select="pbs:code"/>
            <xsl:text> </xsl:text>
        </xsl:if>
    </xsl:template>
    <xsl:template match="*|text()" mode="note"/>
    <xsl:template
        match="rwt:restriction-reference |
        rwt:circumstance-reference |
        rwt:caution-reference"
        mode="caution">

        <xsl:apply-templates select="key('ident', substring(@xlink:href, 2))" mode="caution"/>
    </xsl:template>
    <xsl:template match="rwt:restriction" mode="caution">
        <xsl:apply-templates
            select="rwt:circumstance |
                    rwt:circumstance-reference |
                    rwt:caution-reference"
            mode="caution"/>
    </xsl:template>
    <xsl:template match="rwt:circumstance" mode="caution">
        <xsl:apply-templates select="rwt:caution |
                    rwt:caution-reference"
            mode="caution"/>
    </xsl:template>
    <xsl:template match="rwt:caution" mode="caution">
        <xsl:value-of select="pbs:code"/>
        <xsl:text> </xsl:text>
    </xsl:template>
    <xsl:template match="*|text()" mode="caution"/>

    <xsl:template match="rwt:restriction-reference" mode="eauth.mq">
        <xsl:apply-templates select="key('ident', substring(@xlink:href, 2))" mode="eauth.mq"/>
    </xsl:template>
    <xsl:template match="rwt:restriction" mode="eauth.mq">
        <xsl:apply-templates
            select="rwt:circumstance |
                    rwt:circumstance-reference"
            mode="eauth.mq"/>
    </xsl:template>
    <xsl:template match="rwt:circumstance-reference" mode="eauth.mq">
        <xsl:apply-templates select="key('ident', substring(@xlink:href, 2))" mode="eauth.mq"/>
    </xsl:template>
    <xsl:template match="rwt:circumstance" mode="eauth.mq">
        <xsl:choose>
            <xsl:when test="rwt:authority-method != 'auth:increase-maximum-quantity'"/>
            <xsl:otherwise>
                <xsl:value-of select="rwt:increase/g2g:eauthority"/>
                <xsl:text> </xsl:text>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template match="*|text()" mode="eauth.mq"/>

    <xsl:template match="rwt:restriction-reference" mode="cpap.mq">
        <xsl:apply-templates select="key('ident', substring(@xlink:href, 2))" mode="cpap.mq"/>
    </xsl:template>
    <xsl:template match="rwt:restriction" mode="cpap.mq">
        <xsl:apply-templates
            select="rwt:circumstance |
                    rwt:circumstance-reference"
            mode="cpap.mq"/>
    </xsl:template>
    <xsl:template match="rwt:circumstance-reference" mode="cpap.mq">
        <xsl:apply-templates select="key('ident', substring(@xlink:href, 2))" mode="cpap.mq"/>
    </xsl:template>
    <xsl:template match="rwt:circumstance" mode="cpap.mq">
        <xsl:choose>
            <xsl:when test="rwt:authority-method != 'auth:increase-maximum-quantity'"/>
            <xsl:otherwise>
                <xsl:value-of select="rwt:increase/rwt:cpap"/>
                <xsl:text> </xsl:text>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template match="*|text()" mode="cpap.mq"/>

    <xsl:template match="rwt:restriction-reference" mode="eauth.rpts">
        <xsl:apply-templates select="key('ident', substring(@xlink:href, 2))" mode="eauth.rpts"/>
    </xsl:template>
    <xsl:template match="rwt:restriction" mode="eauth.rpts">
        <xsl:apply-templates
            select="rwt:circumstance |
                    rwt:circumstance-reference"
            mode="eauth.rpts"/>
    </xsl:template>
    <xsl:template match="rwt:circumstance-reference" mode="eauth.rpts">
        <xsl:apply-templates select="key('ident', substring(@xlink:href, 2))" mode="eauth.rpts"/>
    </xsl:template>
    <xsl:template match="rwt:circumstance" mode="eauth.rpts">
        <xsl:choose>
            <xsl:when test="rwt:authority-method != 'auth:increase-number-repeats'"/>
            <xsl:otherwise>
                <xsl:value-of select="rwt:increase/g2g:eauthority"/>
                <xsl:text> </xsl:text>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template match="*|text()" mode="eauth.rpts"/>

    <xsl:template match="rwt:restriction-reference" mode="cpap.rpts">
        <xsl:apply-templates select="key('ident', substring(@xlink:href, 2))" mode="cpap.rpts"/>
    </xsl:template>
    <xsl:template match="rwt:restriction" mode="cpap.rpts">
        <xsl:apply-templates
            select="rwt:circumstance |
                    rwt:circumstance-reference"
            mode="cpap.rpts"/>
    </xsl:template>
    <xsl:template match="rwt:circumstance-reference" mode="cpap.rpts">
        <xsl:apply-templates select="key('ident', substring(@xlink:href, 2))" mode="cpap.rpts"/>
    </xsl:template>
    <xsl:template match="rwt:circumstance" mode="cpap.rpts">
        <xsl:choose>
            <xsl:when test="rwt:authority-method != 'auth:increase-number-repeats'"/>
            <xsl:otherwise>
                <xsl:value-of select="rwt:increase/rwt:cpap"/>
                <xsl:text> </xsl:text>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    <xsl:template match="*|text()" mode="cpap.rpts"/>

    <xsl:template match="rwt:restriction-reference" mode="total.mq">
        <xsl:apply-templates select="key('ident', substring(@xlink:href, 2))" mode="total.mq"/>
    </xsl:template>
    <xsl:template match="rwt:restriction" mode="total.mq">
        <xsl:apply-templates select="rwt:circumstance |
            rwt:circumstance-reference"
            mode="total.mq"/>
    </xsl:template>
    <xsl:template match="rwt:circumstance-reference" mode="total.mq">
        <xsl:apply-templates select="key('ident', substring(@xlink:href, 2))" mode="total.mq"/>
    </xsl:template>
    <xsl:template match="rwt:circumstance" mode="total.mq">
        <xsl:if test="rwt:authority-method = 'auth:increase-maximum-quantity'">
            <xsl:choose>
                <xsl:when test="rwt:increase/g2g:total/node()">
                    <xsl:value-of select="rwt:increase/g2g:total"/>
                    <xsl:text> </xsl:text>
                </xsl:when>
                <xsl:when test="rwt:increase/g2g:total">
                    <xsl:text>unspecified </xsl:text>
                </xsl:when>
            </xsl:choose>
        </xsl:if>
    </xsl:template>
    <xsl:template match="*|text()" mode="total.mq"/>

    <xsl:template match="rwt:restriction-reference" mode="total.rpts">
        <xsl:apply-templates select="key('ident', substring(@xlink:href, 2))" mode="total.rpts"/>
    </xsl:template>
    <xsl:template match="rwt:restriction" mode="total.rpts">
        <xsl:apply-templates select="rwt:circumstance |
            rwt:circumstance-reference"
            mode="total.rpts"/>
    </xsl:template>
    <xsl:template match="rwt:circumstance-reference" mode="total.rpts">
        <xsl:apply-templates select="key('ident', substring(@xlink:href, 2))" mode="total.rpts"/>
    </xsl:template>
    <xsl:template match="rwt:circumstance" mode="total.rpts">
        <xsl:if test="rwt:authority-method = 'auth:increase-number-repeats'">
            <xsl:choose>
                <xsl:when test="rwt:increase/g2g:total/node()">
                    <xsl:value-of select="rwt:increase/g2g:total"/>
                    <xsl:text> </xsl:text>
                </xsl:when>
                <xsl:when test="rwt:increase/g2g:total">
                    <xsl:text>unspecified </xsl:text>
                </xsl:when>
            </xsl:choose>
        </xsl:if>
    </xsl:template>
    <xsl:template match="*|text()" mode="total.rpts"/>

    <xsl:template name="create-row">
        <xsl:param name="item"/>
        <xsl:param name="item-code"/>
        <xsl:param name="level"/>
        <xsl:param name="eauth.mq"/>
        <xsl:param name="eauth.rpts"/>
        <xsl:param name="eauth.flag"/>
        <xsl:param name="sch.ind"/>
        <xsl:param name="start"/>
        <xsl:param name="end"/>
        <xsl:param name="note.ids"/>
        <xsl:param name="caution.ids"/>

        <!-- PBS Item Code -->
        <xsl:call-template name="pad-right">
            <xsl:with-param name="text" select="$item-code"/>
            <xsl:with-param name="length" select="5"/>
        </xsl:call-template>
        <xsl:value-of select="$delimiter"/>
        <!-- Restriction Flag -->
        <xsl:choose>
            <xsl:when
                test="$level = 'authority-required' or
                $level = 'streamlined'"
                >A</xsl:when>
            <xsl:when test="$level = 'restricted'">R</xsl:when>
            <xsl:otherwise>U</xsl:otherwise>
        </xsl:choose>
        <xsl:value-of select="$delimiter"/>

        <xsl:if test="$type = 'normal'">
            <xsl:call-template name="pad-number">
                <xsl:with-param name="number" select="$eauth.mq"/>
                <xsl:with-param name="length" select="2"/>
                <xsl:with-param name="pad" select="'0'"/>
            </xsl:call-template>
        </xsl:if>
        <xsl:value-of select="$delimiter"/>
        <xsl:if test="$type = 'normal'">
            <xsl:call-template name="pad-number">
                <xsl:with-param name="number" select="$eauth.rpts"/>
                <xsl:with-param name="length" select="2"/>
                <xsl:with-param name="pad" select="'0'"/>
            </xsl:call-template>
        </xsl:if>
        <xsl:value-of select="$delimiter"/>
        <xsl:if test="$type = 'normal'">
            <xsl:value-of select="$eauth.flag"/>
        </xsl:if>
        <xsl:value-of select="$delimiter"/>
        <xsl:if test="$type = 'normal'">
            <xsl:value-of select="$sch.ind"/>
        </xsl:if>
        <xsl:value-of select="$delimiter"/>
        <xsl:choose>
            <xsl:when test="normalize-space($start) = '0'"/>
            <xsl:when test="$bug-compatible = 'no'">
                <xsl:call-template name="format-date">
                    <xsl:with-param name="date" select="normalize-space($start)"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:call-template name="format-date-buggy">
                    <xsl:with-param name="date" select="normalize-space($start)"/>
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>
        <xsl:value-of select="$delimiter"/>
        <!-- TODO: subtract one day from non-effective date for end date -->
        <xsl:choose>
            <xsl:when
                test="normalize-space($end) != '' and
                normalize-space($end) != '0'">
                <xsl:call-template name="format-date-minus-1D">
                    <xsl:with-param name="date" select="normalize-space($end)"/>
                    <xsl:with-param name="buggy" select="$bug-compatible"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text>        </xsl:text>
            </xsl:otherwise>
        </xsl:choose>
        <!-- Don't output the delimeter here as it is output by the extract template before each value -->
        <xsl:call-template name="extract">
            <xsl:with-param name="text" select="$note.ids"/>
            <xsl:with-param name="number" select="15"/>
        </xsl:call-template>
        <!-- Don't output the delimeter here as it is output by the extract template before each value -->
        <xsl:call-template name="extract">
            <xsl:with-param name="text" select="$caution.ids"/>
            <xsl:with-param name="number" select="5"/>
        </xsl:call-template>
        <xsl:value-of select="$eol"/>
    </xsl:template>

    <xsl:template name="extract">
        <xsl:param name="text"/>
        <xsl:param name="previous_values" select="' '"/>
        <xsl:param name="number" select="0"/>

        <xsl:choose>
            <xsl:when test="$number &lt;= 0"/>
            <xsl:otherwise>
                <xsl:variable name="next">
                    <xsl:choose>
                        <xsl:when test="contains($text, ' ')">
                            <xsl:value-of select="substring-before($text, ' ')"/>
                        </xsl:when>
                        <xsl:when test="$text != ''">
                            <xsl:value-of select="$text"/>
                        </xsl:when>
                        <xsl:otherwise>0</xsl:otherwise>
                    </xsl:choose>
                </xsl:variable>
                <!-- If the current value is non-numeric or a duplicate, output nothing and don't decrease the counter. This is to prevent empty '0000' values between valid values. -->
                <xsl:variable name="nextNumber">
                    <xsl:choose>
                        <xsl:when
                            test="$next = '0' or
                            (string(number($next)) != 'NaN' and not(contains($previous_values, concat(' ',$next,' '))))">
                            <xsl:value-of select="$number - 1"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="$number"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:variable>
                <xsl:if test="$nextNumber != $number">
                    <xsl:value-of select="$delimiter"/>
                    <xsl:choose>
                        <xsl:when test="$type = 'normal'">
                            <xsl:value-of select="format-number($next,'0000')"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="$next"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:if>
                <xsl:call-template name="extract">
                    <xsl:with-param name="number" select="$nextNumber"/>
                    <xsl:with-param name="text" select="substring-after($text, ' ')"/>
                    <xsl:with-param name="previous_values"
                        select="concat($previous_values, $next, ' ')"/>
                    <xsl:with-param name="delimiter" select="$delimiter"/>
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>
